//
// Copyright (c) 2024 BPer
//

#include <bperstream/BPerStreamRtc.h>

#include <bperutil/sys/BPerLog.h>
#include <bperutil/BPerAvInfoType.h>
#include <bperrtc/BPerPeerConnection.h>


int32_t bPer_stream_rtc_isconnected(BPerStreamContext* context){
	if(context==NULL||context->context==NULL) return 0;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	return rtc->isConnected(&rtc->peer);
}
int32_t bPer_stream_rtc_isAlive(BPerStreamContext* context){
	if(context==NULL||context->context==NULL) return 0;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	return rtc->isAlive(&rtc->peer);
}
int32_t bPer_stream_rtc_getConnectState(BPerStreamContext* context){

	if(context==NULL||context->context==NULL) return ERROR_SOCKET;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	return rtc->isConnected(&rtc->peer)?BPer_Ok:ERROR_SOCKET;
}
int32_t bPer_stream_rtc_disConnectServer(BPerStreamContext* context){
	if(context==NULL||context->context==NULL) return 1;
	context->netState=1;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	return rtc->close(&rtc->peer);
}
int32_t bPer_stream_rtc_reconnect(BPerStreamContext* context) {
	if(context==NULL||context->context==NULL) return 1;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	return rtc->connectSfuServer(&rtc->peer);
}
int32_t bPer_stream_rtc_connectServer(BPerStreamContext* context) {
	if(context==NULL||context->context==NULL) return 1;

	if(bPer_stream_rtc_isconnected(context)) return BPer_Ok;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;

	rtc->init(&rtc->peer);
	context->netState=bPer_stream_rtc_reconnect(context);
	return context->netState;

}



int32_t bPer_stream_rtc_publishAudioData(BPerStreamContext* context,BPerStreamCapture *audioFrame) {
	if(context==NULL||context->context==NULL) return 1;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	if(rtc->on_audio) return rtc->on_audio(&rtc->peer,audioFrame->getAudioFrame(audioFrame->context));
	return BPer_Ok;
}

int32_t bPer_stream_rtc_publishVideoData(BPerStreamContext* context,BPerStreamCapture* videoFrame) {
	if(context==NULL||context->context==NULL) return 1;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	if(rtc->on_video) return rtc->on_video(&rtc->peer,videoFrame->getVideoFrame(videoFrame->context));
	return BPer_Ok;
}

int32_t bPer_stream_rtc_publishMsg(BPerStreamContext* context,BPerFrame* msgFrame) {
	if(context==NULL||context->context==NULL) return 1;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	if(rtc->on_message) return rtc->on_message(&rtc->peer,msgFrame);
	return BPer_Ok;
}
int32_t bPer_stream_rtc_receiveData(BPerStreamContext* context,int32_t *plen) {

	return BPer_Ok;
}
int32_t bPer_stream_rtc_sendNotifyMsg(BPerStreamContext* context,BPerRtcMessageType mess){
	if(context==NULL||context->context==NULL) return 1;
	BPerPeerConnection* rtc=(BPerPeerConnection*)context->context;
	if(rtc->sendRtcMessage) rtc->sendRtcMessage(&rtc->peer,mess);
	return BPer_Ok;
}

void bPer_create_stream_rtc(BPerStreamHandle* handle){
	if(handle==NULL||handle->context==NULL) return;
	handle->context->context=bPer_calloc(sizeof(BPerPeerConnection),1);
	BPerPeerConnection* rtc=(BPerPeerConnection*)handle->context->context;
	rtc->peer.avinfo=handle->context->avinfo;
	bPer_memcpy(&rtc->peer.streamconfig,&handle->context->streamconfig,sizeof(BPerStreamConfig));
	bPer_create_peerConnection(rtc);



	handle->connectServer=bPer_stream_rtc_connectServer;
	handle->disConnectServer=bPer_stream_rtc_disConnectServer;
	handle->getConnectState=bPer_stream_rtc_getConnectState;
	handle->isAlive=bPer_stream_rtc_isAlive;
	handle->isconnected=bPer_stream_rtc_isconnected;
	handle->publishAudioData=bPer_stream_rtc_publishAudioData;
	handle->publishVideoData=bPer_stream_rtc_publishVideoData;
	handle->publishMsg=bPer_stream_rtc_publishMsg;
	handle->receiveData=bPer_stream_rtc_receiveData;
	handle->reconnect=bPer_stream_rtc_reconnect;
	handle->sendRtcMessage=bPer_stream_rtc_sendNotifyMsg;
}
void bPer_destroy_stream_rtc(BPerStreamHandle* handle){
	if(handle==NULL||handle->context==NULL) return;
	BPerPeerConnection* rtc=(BPerPeerConnection*)handle->context->context;
	bPer_destroy_peerConnection(rtc);
	bPer_free(rtc);
}
